package mbp.tests;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import mbp.base.EnumType;
import mbp.base.FeatureType;
import mbp.base.ResourceType;
import mbp.core.Resource;
import mbp.core.ResourceTypeBuilder;
import mbp.core.ResourceValidation;
import mbp.exceptions.InvalidFeatureNameException;
import mbp.exceptions.InvalidFeatureTypeException;
import mbp.exceptions.InvalidFeatureValueException;
import mbp.exceptions.ParseExpressionErrorException;
import mbp.message.ObjectBuilder;

public class RandomObject 
{
	Random generator = new Random();
	private int amount;
	public RandomObject(int amount)
	{
		this.amount = amount;
	}
	
	/**
	 * Zwraca liste zasobow spelniajacych warunek rcv
	 * @param rcv warunek akceptowalnosci
	 * @param rc zasob wzorcowy, potrzebny do inicjalizacji parametrow generatora 
	 * @param size ilosc zasobow jakie ma zostac zwrocona
	 * @return
	 */
	public List<Resource> randomResource2(ResourceValidation rcv, Resource rc, int size)
	{
		List<Resource> rcList = new ArrayList<Resource>();
		String rcType = rc.getType().getResourceTypeName();
		if(rcType.compareTo(rcv.getType().getResourceTypeName())!=0)
		{
			System.out.println("Wrong type");
			return null;
		}		
		ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
		
		// | key | par1 | par2 | value |
		Map<String, Object[]> randomVaues = new HashMap<String, Object[]>();
		
		HashMap<String, FeatureType> features = rc.getType().getFeaturesCollection();
		Iterator<String> it = features.keySet().iterator();
		while(it.hasNext())
		{
			String key = it.next();
			FeatureType fType = features.get(key);
			switch(fType)
			{
			case INT:
				//generator.nextInt(ipar1) + ipar2
				Integer vint;
				try {
					vint = (Integer) rc.getFeatureValue(key);
					int ioffset = vint * 10;
					int ipar1 = vint + ioffset;
					int ipar2 = vint - ioffset;
					if(ipar2<0) ipar2 = 0;
					randomVaues.put( key, new Object[]{FeatureType.INT, new Integer(ipar1), new Integer(ipar2), null} );
				} catch (InvalidFeatureNameException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;
			case FLOAT:
				//generator.nextFloat() + fpar1 ) * fpar2
				Float vfloat;
				try {
					vfloat = (Float) rc.getFeatureValue(key);
					int foffset = (int) (vfloat * 2);
					randomVaues.put( key, new Object[]{FeatureType.FLOAT, new Integer(0), new Integer(foffset), null} );
				} catch (InvalidFeatureNameException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;
			case ENUM:
				EnumType et = rc.getType().getEnumTypes().get(key);
				int epar1 = et.getArray().length;
				randomVaues.put( key, new Object[]{FeatureType.ENUM, new Integer(epar1), new Integer(0), null} );
				break;
			}		
		}
		
		for(int i = 0; i<10000; i++)
		{
			Resource rcGen = new Resource(rtb.GetResourceType(rcType));
			Iterator<String> it2 = randomVaues.keySet().iterator();
			while(it2.hasNext())
			{
				String key = it2.next();
				//System.out.println(key + " " + randomVaues.get(key)[0] + " " + randomVaues.get(key)[1] + " " + randomVaues.get(key)[2]);
				FeatureType fType = (FeatureType) randomVaues.get(key)[0];
				int par1 = (Integer) randomVaues.get(key)[1];
				int par2 = (Integer) randomVaues.get(key)[2];
				switch(fType)
				{
				case INT:
					//generator.nextInt(ipar1) + ipar2
					randomVaues.get(key)[3] = generator.nextInt(par1) + par2;
					break;
				case FLOAT:
					//generator.nextFloat() + fpar1 ) * fpar2
					randomVaues.get(key)[3] = ( generator.nextFloat() + par1 ) * par2;
					break;
				case ENUM:
					randomVaues.get(key)[3] = generator.nextInt(par1) + par2;
					break;
				}
			
				//System.out.println(key + " " + randomVaues.get(key)[0] + " " 
				//			+ randomVaues.get(key)[1] + " " + randomVaues.get(key)[2] + " " + randomVaues.get(key)[3]);
			
				try {
					rcGen.setFeatureValue(key, randomVaues.get(key)[3]);
				} catch (InvalidFeatureNameException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvalidFeatureTypeException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvalidFeatureValueException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
			}
			rcGen.setValidDate(new Date());
			try {
				if(rcv.validateCondition(rcGen))
				{
					rcList.add(rcGen);
				}
			} catch (ParseExpressionErrorException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			//rcGen.printResourceInfo();
			if(rcList.size() == size)
			{
				break;
			}
		}
		
		return rcList;
	}
	
	/**
	 * Zwraca zasob z losowo wygenerowanymi wartosciami cech
	 * @param type
	 * @return
	 */
	public Resource randomResource(String type)
	{
		int ipar1 = 1000;
		int ipar2 = 0;
		int fpar1 = 0;
		int fpar2 = 100;
		
		ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
		ResourceType rcType = rtb.GetResourceType(type);
		Resource rc = new Resource(rcType);
		
		Map<String, Object> randomVaues = new HashMap<String, Object>();
		HashMap<String, FeatureType> features = rc.getType().getFeaturesCollection();
		Iterator<String> it = features.keySet().iterator();
		while(it.hasNext())
		{
			String key = it.next();
			FeatureType fType = features.get(key);
			switch(fType)
			{
			case INT:
				randomVaues.put(key, generator.nextInt(ipar1) + ipar2);
				break;
			case FLOAT:
				randomVaues.put(key, ( generator.nextFloat() + fpar1 ) * fpar2);
				break;
			case ENUM:
				EnumType et = rc.getType().getEnumTypes().get(key);
				int size = et.getArray().length;
				randomVaues.put(key, generator.nextInt(size));
				break;
			}		
		}
		
		Iterator<String> it2 = randomVaues.keySet().iterator();
		while(it2.hasNext())
		{
			String key = it2.next();
			try {
				if(key.compareTo("AMOUNT")==0)
				{
					rc.setFeatureValue(key, 1);
				}
				else
				{
					rc.setFeatureValue(key, randomVaues.get(key));
				}
			} catch (InvalidFeatureNameException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvalidFeatureTypeException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvalidFeatureValueException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return rc;
	}
	
	public List<Resource> randomResource(ResourceValidation rcv)
	{
		List<Resource> rcList = new ArrayList<Resource>();
		String type = rcv.getType().getResourceTypeName();
		
		for(int i = 0; i< 100; i++)
		{
			rcList.add(randomResource(type));
		}
		
		return rcList;
	}

}
